﻿//---------------------------------------------------------------------------
//
// Copyright (C) Inter Access B.V..  All rights reserved.
//
//---------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Schedule.Primitives
{
    /// <summary>
    /// ItemsPresenter that uses a TimePanel to present TimeItems
    /// </summary>
    public class TimeItemsPresenter : ItemsControl
    {
        public TimeItemsPresenter()
        {
            
        }

        static TimeItemsPresenter()
        {
            DefaultStyleKeyProperty.OverrideMetadata(
                typeof(TimeItemsPresenter), 
                new FrameworkPropertyMetadata(typeof(TimeItemsPresenter)));

            // Create a TimePanel
            ItemsPanelTemplate defaultValue = new ItemsPanelTemplate(new FrameworkElementFactory(typeof(TimePanel)));

            // We need these bindings to tell the ItemPanel wich timespan to display
            Binding startBinding = new Binding("Start");
            startBinding.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(TimeItemsPresenter), 1);
            Binding endBinding = new Binding("End");
            endBinding.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(TimeItemsPresenter), 1);

            defaultValue.VisualTree.SetBinding(TimePanel.StartProperty, startBinding);
            defaultValue.VisualTree.SetBinding(TimePanel.EndProperty, endBinding);

            // Add the timepanel to the default meta data
            ItemsControl.ItemsPanelProperty.OverrideMetadata(typeof(TimeItemsPresenter), new FrameworkPropertyMetadata(defaultValue));
        }        

        #region Properties

        /// <summary>
        /// DateTime to present from
        /// </summary>
        public DateTime Start
        {
            get { return (DateTime)GetValue(StartProperty); }
            set { SetValue(StartProperty, value); }
        }

        public static readonly DependencyProperty StartProperty =
            DependencyProperty.Register("Start", typeof(DateTime), typeof(TimeItemsPresenter), new UIPropertyMetadata(OnStartPropertyChanged));

        private static void OnStartPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {

        }

        /// <summary>
        /// DateTime to present to
        /// </summary>
        public DateTime End
        {
            get { return (DateTime)GetValue(EndProperty); }
            set { SetValue(EndProperty, value); }
        }

        public static readonly DependencyProperty EndProperty =
            DependencyProperty.Register("End", typeof(DateTime), typeof(TimeItemsPresenter), new UIPropertyMetadata(OnEndPropertyChanged));

        private static void OnEndPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {

        }

        #endregion

        #region Methods

        private static void OnItemStartChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }

        private static void OnItemEndChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }

        private static object OnItemStartCoerce(DependencyObject d, object baseValue)
        {
            TimeItemsPresenter owningItemsControl = ItemsControl.GetItemsOwner(d) as TimeItemsPresenter;
            if (owningItemsControl != null)
            {
                DateTime typedValue = (DateTime)baseValue;
                if (typedValue < owningItemsControl.Start)
                {
                    return owningItemsControl.Start;
                }
            }
            return baseValue;
        }

        private static object OnItemEndCoerce(DependencyObject d, object baseValue)
        {
            TimeItemsPresenter owningItemsControl = ItemsControl.GetItemsOwner(d) as TimeItemsPresenter;
            if (owningItemsControl != null)
            {
                DateTime typedValue = (DateTime)baseValue;
                if (typedValue > owningItemsControl.End)
                {
                    return owningItemsControl.End;
                }
            }
            return baseValue;
        }

        #endregion

        #region Overrides

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
        }

        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            // Only TimeItems can be presented without wrapping
            return item is TimeItem;
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            // return a new container for the object
            return new TimeItem();
        }

        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            // TODO: Bind to property user has described

            // If it's not a timeitem, we need to add some bindings
            if (!(item is TimeItem))
            {
                TimeItem typedItem = (TimeItem)element;

                // Start binding
                Binding startBinding = new Binding();
                startBinding.Path = new PropertyPath("Start");

                // End binding
                Binding endBinding = new Binding();
                endBinding.Path = new PropertyPath("End");

                // Add the bindings
                typedItem.SetBinding(TimePanel.ItemStartProperty, startBinding).UpdateTarget();
                typedItem.SetBinding(TimePanel.ItemEndProperty, endBinding).UpdateTarget();
            }
            
            // Call the base method
            base.PrepareContainerForItemOverride(element, item);
        }

        #endregion
    }
}
